/*
 * @Description: 
 * @Author: Hadlee
 * @Date: 2024-11-10 21:07:06
 */
#include "pdiusbd12.h"
#include "config.h"
#include "MyType.h"
#include "uart.h"

#include <stdio.h>

void DelayXms(uint16_t x)
{
	uint16_t i;
	uint16_t j;
	for(i=0;i<x;i++)
	for(j=0;j<227;j++);
}

/**************************************************************
function: D12 write Cmd
input:command one byte cmd
return: None
Note: None
**************************************************************/
void D12WriteCommand(uint8_t cmd)
{
	D12SetCommandAddr(); // 设置总线为指令
	D12ClrWr(); // 打开写数据有效
	D12SetPortOut(); // MCU数据口为输出
	D12SetData(cmd); // 发送数据
	D12SetWr(); // 关闭写数据有效
	D12SetPortIn(); // 设置数据总线为输入，准备读数据
}

/**************************************************************
function: read one byte from D12
input:None
return: readed one byte
Note: None
**************************************************************/
uint8_t D12ReadByte(void)
{
	uint8_t tmp;
	D12SetDataAddr(); // 设置总线为数据线
	D12ClrRd(); // 打开读数据有效
	tmp = D12GetData(); // 读数据
	D12SetRd(); // 关闭读数据有效
	return tmp;
}

/**************************************************************
function: write one byte to D12
input: write value
return: None
Note: None
**************************************************************/
void D12WriteByte(uint8_t Value)
{
	D12SetDataAddr();		// 设置为数据地址
	D12ClrWr();				// WR置低
	D12SetPortOut();		// 将数据口设置为输出状态（暂时为空）
	D12SetData(Value);		// 写出数据
	D12SetWr();				// WR置高
	D12SetPortIn();			// 将数据口设置为输入状态
}

/**************************************************************
function: read D12 ID
input:None
return: D12 ID
Note: None
**************************************************************/
uint16_t D12ReadID(void)
{
	uint16_t id;
	D12WriteCommand(Read_ID);
	id = D12ReadByte();
	id |= ((uint16_t)D12ReadByte())<<8;
	return id;
}

/**************************************************************
function: select usb port function
input: Endp:0~5, in/out point
return: None
Note: None
**************************************************************/
void D12SelectEndPoint(uint8_t Endp)
{
	D12WriteCommand(0x00 + Endp);  // select port cmd
}

/**************************************************************
function: read point buffer function
input: Endp:0~5, in/out point
return: actual read data length
**************************************************************/
uint8_t D12ReadEndPointBuffer(uint8_t Endp, uint8_t Len, uint8_t* buffer)
{
	uint8_t j = 0, i = 0;
	D12SelectEndPoint(Endp);
	D12WriteCommand(D12_READ_BUFFER);
	D12ReadByte(); 		// read first reserv data;
	j = D12ReadByte();	// read buffer len data;
	if(j > Len){
		j = Len;
	}

#ifdef DEBUG
	// printf("Read point:%d, len:%d \r\n", Endp, j);
	Prints("read ep: ");
	PrintLongInt(Endp);
	Prints(",buffer len: ");
	PrintLongInt(j);
	Prints("\r\n");

#endif

	for(i = 0;i < j; i++) {
		D12ClrRd();
		*(buffer+i) = D12GetData();
		D12SetRd();
#ifdef DEBUG
	PrintHex(*(buffer+i)); //如果需要显示调试信息，则显示读到的数据
	if(((i+1)%16)==0) Prints("\r\n"); //每16字节换行一次
#endif
	}

#ifdef DEBUG
	if((j%16) != 0) Prints("\r\n"); //每16字节换行一次
#endif

	return j;
}

static void D12ValidateBuffer(void)
{
 	D12WriteCommand(D12_VALIDATE_BUFFER);
}

uint8_t D12WriteEndPointBuffer(uint8_t Endp, uint8_t Len, uint8_t *buffer)
{
	uint8_t i;
	D12SelectEndPoint(Endp);  // select dst end point.
	D12WriteCommand(D12_WRITE_BUFFER);	// write buffer cmd
	D12WriteByte(0);		// msut write 0.
	D12WriteByte(Len);		// write need send data length.
	
	D12SetPortOut();  // set data port out mode.
	for(i=0;i<Len;i++)
	{
		D12ClrWr();
		D12SetData(*(buffer+i));
		D12SetWr();
		PrintHex(*(buffer+i));  //如果需要显示调试信息，则显示发送的数据
		if(((i+1)%16)==0)Prints("\r\n"); //每16字节换行一次
	}
	
	// set data port IN mode.
	D12SetPortIn();
	D12ValidateBuffer();  // validate point buffer data.

	// printf("write point:%d, len:%d.\r\n", Endp, Len);
	Prints("write ep: ");
	PrintLongInt(Endp/2);
	Prints(",buffer len: ");
	PrintLongInt(Len);
	Prints("\r\n");

	return Len;
}

// clear end point buffer.
void D12ClearBuffer(void)
{
	D12WriteCommand(D12_CLEAR_BUFFER);
}

void D12AcknowledgeSetup(void)
{
	D12SelectEndPoint(1);  // select EndPoint-0 IN.
	D12WriteCommand(D12_ACKNOWLEDGE_SETUP);
	D12SelectEndPoint(0); // select EndPoint-0 OUT
	D12WriteCommand(D12_ACKNOWLEDGE_SETUP);
}

uint8_t D12ReadEndPointLastStatus(uint8_t Endp)
{
	D12WriteCommand(0x40+Endp);
	return D12ReadByte();
}

void D12SetAddress(uint8_t addr)
{
	D12WriteCommand(D12_SET_ADDRESS_ENABLE); // write set address cmd
	D12WriteByte(0x80 | addr);				// write 1 byte data, and enable addr
}

void D12SetEndpointEnable(uint8_t Enable)
{
	D12WriteCommand(D12_SET_ENDPOINT_ENABLE);
	if(Enable != 0)
	{
		D12WriteByte(0x01); // D0为1，使能端点
	}
	else
	{
		D12WriteByte(0x0); // D0为0，不使能端点
	}
}
















